package service

import (
	"context"
	"go-admin/server/internal/domain"
	clientv3 "go.etcd.io/etcd/client/v3"
	"gopkg.in/yaml.v2"
	"strings"
	"unicode/utf8"
)

type SettingService interface {
	Save(ctx context.Context, setting domain.Setting) error
	GetInfo(ctx context.Context) domain.Setting
}

type settingService struct {
	etcdKv clientv3.KV
}

func NewSettingService(etcdKv clientv3.KV) SettingService {
	return &settingService{
		etcdKv: etcdKv,
	}
}

func (s *settingService) Save(ctx context.Context, set domain.Setting) error {
	key := "/webook"
	var config domain.SettingConfig
	getResponse, err := s.etcdKv.Get(ctx, key)
	if len(getResponse.Kvs) > 0 {
		_ = yaml.Unmarshal(getResponse.Kvs[0].Value, &config)
	}
	if set.AliyunSecretId != "" && !s.containsAsterisk(set.AliyunSecretId) {
		config.SMS.Aliyun.SecretId = set.AliyunSecretId
	}

	if set.AliyunSecretKey != "" && !s.containsAsterisk(set.AliyunSecretKey) {
		config.SMS.Aliyun.SecretKey = set.AliyunSecretKey
	}

	if set.AliyunSignaName != "" && !s.containsAsterisk(set.AliyunSignaName) {
		config.SMS.Aliyun.SignaName = set.AliyunSignaName
	}

	if set.TencentSecretId != "" && !s.containsAsterisk(set.TencentSecretId) {
		config.SMS.Tencent.SecretId = set.TencentSecretId
	}

	if set.TencentSecretKey != "" && !s.containsAsterisk(set.TencentSecretKey) {
		config.SMS.Tencent.SecretKey = set.TencentSecretKey
	}

	if set.TencentSignaName != "" && !s.containsAsterisk(set.TencentSignaName) {
		config.SMS.Tencent.SignaName = set.TencentSignaName
	}

	if set.TencentAppId != "" && !s.containsAsterisk(set.TencentAppId) {
		config.SMS.Tencent.AppId = set.TencentAppId
	}
	config.SMS.Aliyun.Region = "cn-hangzhou"
	config.SMS.Tencent.Region = "ap-beijing"

	configYAML, err := yaml.Marshal(&config)
	_, err = s.etcdKv.Put(ctx, key, string(configYAML))

	if err != nil {
		return err
	}

	//configFile := "config/setting.yaml"
	//timestamp := time.Now().Unix()
	//updatedConfigData, err := yaml.Marshal(timestamp)
	//_ = ioutil.WriteFile(configFile, updatedConfigData, 0644)

	return nil
}

func (s *settingService) GetInfo(ctx context.Context) domain.Setting {
	key := "/webook"
	getResponse, err := s.etcdKv.Get(ctx, key)
	if err != nil {
		return domain.Setting{}
	}
	if len(getResponse.Kvs) > 0 {
		var config domain.SettingConfig
		err = yaml.Unmarshal(getResponse.Kvs[0].Value, &config)
		if err != nil {
			return domain.Setting{}
		}
		return domain.Setting{
			AliyunSecretId:   s.maskString(config.SMS.Aliyun.SecretId, 3, 3),
			AliyunSecretKey:  s.maskString(config.SMS.Aliyun.SecretKey, 3, 3),
			AliyunSignaName:  config.SMS.Aliyun.SignaName,
			TencentSecretId:  s.maskString(config.SMS.Tencent.SecretId, 3, 3),
			TencentSecretKey: s.maskString(config.SMS.Tencent.SecretKey, 3, 3),
			TencentSignaName: config.SMS.Tencent.SignaName,
			TencentAppId:     s.maskString(config.SMS.Tencent.AppId, 2, 2),
		}
	}
	return domain.Setting{}
}

func (s *settingService) maskString(str string, keepStart, keepEnd int) string {
	strLen := utf8.RuneCountInString(str)
	if strLen <= keepStart+keepEnd {
		return str
	}

	runes := []rune(str)
	maskedPart := strings.Repeat("*", strLen-keepStart-keepEnd)
	maskedStr := string(runes[:keepStart]) + maskedPart + string(runes[strLen-keepEnd:])
	return maskedStr
}

func (s *settingService) containsAsterisk(str string) bool {
	return strings.Contains(str, "*")
}
